package nl.weeaboo.sh.view;

import java.awt.Dimension;
import java.awt.Rectangle;

import javax.media.opengl.GL;

import nl.weeaboo.game.gl.GLDraw;
import nl.weeaboo.game.gl.GLManager;
import nl.weeaboo.sh.Game;
import nl.weeaboo.sh.GameFrame;
import nl.weeaboo.sh.level.AbstractLevel;
import nl.weeaboo.sh.level.ActiveTiles;
import nl.weeaboo.sh.level.Level;
import nl.weeaboo.sh.level.Tile;
import nl.weeaboo.sh.objects.Effect;
import nl.weeaboo.sh.objects.Sprite;
import timon.common.GraphicsUtil;

public class GameView {

	private Game game;
	
	public GameView(Game g) {
		this.game = g;		
	}

	//Functions
	public void draw(GLManager glm, int rw, int rh) {
		AbstractLevel al = game.getLevel();
		if (al != null) {
			GL gl = glm.getGL();
			gl.glPushMatrix();
			
			int w = GameFrame.defaultWidth;
			int h = GameFrame.defaultHeight;
			
			Dimension d = GraphicsUtil.getProportionalScale(w, h, rw, rh);
			int dx1 = (rw - d.width) / 2;
			int dx2 = (rw - d.width) - dx1;
			int dy1 = (rh - d.height) / 2;			
			int dy2 = (rh - d.height) - dy1;			
			glm.translate(dx1, dy1);

			gl.glPushMatrix();			
			double scaleX = (double)d.width / w;
			double scaleY = (double)d.height / h;
			gl.glScaled(scaleX, scaleY, 1);		

			Level level = (al instanceof Level ? (Level)al : null);
			
			if (!al.isForegroundOpaque()) {
				if (level != null) {
					glm.pushColor();
					if (level.getUniverseAdapter() != null) {
						glm.mixColor(.5f, .5f, .5f, 1);
					}
				}
				
				al.drawBackground(glm, w, h);
				
				if (level != null) {
					glm.popColor();
					drawLevel(glm, level, w, h);
				}
			}
			al.drawForeground(glm, w, h);
			
			gl.glPopMatrix();

			if (Game.debugCgTest) {
				game.getCgManager().test(glm, game.getImage("conv_sprite.png", true), w, h);
			}
			
			glm.setColor(0, 0, 0, 1.0f);
			glm.setTexture(null);
			glm.translate(-dx1, -dy1);
			GLDraw.clearRect(gl, 0, 0, dx1, rh, 0, 0, 0);
			GLDraw.clearRect(gl, rw-dx2, 0, dx2, rh, 0, 0, 0);
			GLDraw.clearRect(gl, dx1, 0, rw-dx1-dx2, dy1, 0, 0, 0);
			GLDraw.clearRect(gl, dx1, rh-dy2, rw-dx1-dx2, dy2, 0, 0, 0);

			gl.glPopMatrix();
		}
	}
	
	public void drawLevel(GLManager glm, Level level, int w, int h) {
		GL gl = glm.getGL();
		gl.glPushMatrix();
		
		glm.pushColor();
		
		Camera camera = level.getCamera();
		int cxs = camera.getX();
		int cys = camera.getY();
		float cs = camera.getScale();
		
		float tx = -cxs + (w >>> 1) / cs;
		float ty = -cys + (h >>> 1) / cs;

		glm.scale(cs, cs);
		gl.glTranslatef(tx, ty, 0);	
		
		if (level.getUniverseAdapter() != null) {
			level.getUniverseAdapter().drawBackground(glm);
		}

		//Draw Tiles
		int minX = Level.toTileCoord(cxs - (w >>> 1) / cs);
		int maxX = Level.toTileCoord(cxs + (w >>> 1) / cs + 1);
		int minY = Level.toTileCoord(cys - (h >>> 1) / cs);
		int maxY = Level.toTileCoord(cys + (h >>> 1) / cs + 1);

		drawTiles(glm, level, true, minX, maxX, minY, maxY);
		
		glm.setColor(1, 1, 1, 1);
		gl.glEnable(GL.GL_BLEND);
				
		for (Effect e : level.getEffects()) {
			e.drawBackground(glm);
		}
		for (Sprite s : level.getSprites()) {
			s.draw(glm);
		}

		if (level.getUniverseAdapter() != null) {
			level.getUniverseAdapter().draw(glm);
		}

		drawTiles(glm, level, false, minX, maxX, minY, maxY);

		for (Effect e : level.getEffects()) {
			e.drawForeground(glm);
		}
		for (Sprite s : level.getSprites()) {
			s.drawForeground(glm);
		}

		glm.popColor();
		gl.glPopMatrix();	
	}
	
	protected void drawTiles(GLManager glm, Level level, boolean background,
			int minX, int maxX, int minY, int maxY)
	{
		GL gl = glm.getGL();
		int ts = Level.tileSize;

		ActiveTiles at = level.getActiveTiles();
		Rectangle bounds = at.getBounds();
		Tile tiles[][] = at.getTiles();

		for (int y = minY; y <= maxY; y++) {
			gl.glPushMatrix();
			
			glm.translate(minX * ts, y * ts);
			for (int x = minX; x <= maxX; x++) {
				int ix = x-bounds.x; int iy = y-bounds.y;
				if (ix >= 0 && ix < bounds.width && iy >= 0 && iy < bounds.height) {
					Tile tile = tiles[x-bounds.x][y-bounds.y];
					if (tile != null) {
						if (background) tile.drawBackground(glm, ts);
						else tile.drawForeground(glm, ts);
					}
				}

				glm.translate(ts - .0001f, 0);
			}
			
			gl.glPopMatrix();
		}		
	}		
	
	//Getters
	
	//Setters
	
}
